package net.nohaven.proj.javeau.ui;

import java.awt.Component;
import java.util.Arrays;
import java.util.Comparator;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

import net.nohaven.proj.javeau.fs.FSUtils;
import net.nohaven.proj.javeau.fs.crypt.CFSUtils;
import net.nohaven.proj.javeau.fs.model.FSDirectory;
import net.nohaven.proj.javeau.fs.model.FSItem;
import net.nohaven.proj.javeau.fs.model.Filesystem;

public class FSTableManager extends DefaultTableCellRenderer implements
		TableModel {
	private static final long serialVersionUID = -7766398012946282256L;

	private static final Icon FILE_ICO = new ImageIcon(FSTableManager.class
			.getResource("icon/file.png"));
	private static final Icon DIR_ICO = new ImageIcon(FSTableManager.class
			.getResource("icon/folder.png"));
	private static final Icon DRV_ICO = new ImageIcon(FSTableManager.class
			.getResource("icon/drive-harddisk.png"));
	private static final Icon SEC_ICO = new ImageIcon(FSTableManager.class
			.getResource("icon/lock.png"));

	public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {

		super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
				row, column);

		//defaults
		setIcon(null);
		setHorizontalAlignment(JLabel.LEFT);

		switch (column) {
		case (0): {
			if (FSUtils.isFile(items[row]))
				setIcon(FILE_ICO);
			else if (((FSDirectory) items[row]).isDevice())
				setIcon(DRV_ICO);
			else if (CFSUtils.isSecretDirectory((FSDirectory) items[row]))
				setIcon(SEC_ICO);
			else
				setIcon(DIR_ICO);
			break;
		}
		case (1): {
			setHorizontalAlignment(JLabel.RIGHT);
			break;
		}
		}

		return this;
	}

	private Filesystem filesystem;

	private FSItem[] items;

	private FSPanelCompanion panel;

	public FSTableManager(Filesystem filesystem, FSPanelCompanion panel) {
		this.filesystem = filesystem;
		this.panel = panel;

		panel.gui.tblContents.setModel(this);
		panel.gui.tblContents.getColumnModel().getColumn(0).setCellRenderer(
				this);
		panel.gui.tblContents.getColumnModel().getColumn(1).setCellRenderer(
				this);
		setPreferredColumnWidths(panel.gui.tblContents, 0.8, 0.1, 0.1);
	}

	public void calcView() {
		items = filesystem.ls();

		Arrays.sort(items, new Comparator<FSItem>() {
			public int compare(FSItem i1, FSItem i2) {
				if (FSUtils.isDir(i1) && !FSUtils.isDir(i2))
					return -1;
				if (FSUtils.isDir(i2) && !FSUtils.isDir(i1))
					return 1;
				return i1.getName().toLowerCase().compareTo(
						i2.getName().toLowerCase());
			}
		});
	}

	public void addTableModelListener(TableModelListener arg0) {
	}

	public Class<?> getColumnClass(int idx) {
		return String.class;
	}

	private static final String[] COL_NAMES = new String[] { "Name", "Size",
			"Perm" };

	public int getColumnCount() {
		return COL_NAMES.length;
	}

	public String getColumnName(int idx) {
		return COL_NAMES[idx];
	}

	public int getRowCount() {
		if (items == null)
			return 0;
		return items.length;
	}

	public Object getValueAt(int row, int col) {
		switch (col) {
		case 0:
			return items[row].getName();
		case 1:
			return FSUtils.isDir(items[row]) ? "" : FSUtils
					.getSizeString(items[row]);
		case 2:
			String ret = FSUtils.isDir(items[row]) ? "dr" : "-r";
			ret += items[row].canWrite() ? "w" : "-";
			return ret;
		}
		return "";
	}

	public boolean isCellEditable(int row, int col) {
		return false;
	}

	public void removeTableModelListener(TableModelListener arg0) {
	}

	public void setValueAt(Object arg0, int arg1, int arg2) {
	}

	public static void setPreferredColumnWidths(JTable tbl,
			double... percentages) {
		int tableWid = tbl.getPreferredSize().width;
		TableColumnModel colModel = tbl.getColumnModel();

		double tot = 0;
		for (int i = 0; i < colModel.getColumnCount(); i++)
			tot += percentages[i];

		for (int i = 0; i < colModel.getColumnCount(); i++) {
			TableColumn column = colModel.getColumn(i);
			column.setPreferredWidth((int) (tableWid * (percentages[i] / tot)));
		}
	}

	public String[] getSelectedNames() {
		int[] idxs = panel.gui.tblContents.getSelectedRows();
		String[] ret = new String[idxs.length];

		for (int i = 0; i < idxs.length; i++)
			ret[i] = items[idxs[i]].getName();

		return ret;
	}
}
